﻿using Microsoft.AspNetCore.Authorization;
using System.Linq.Dynamic.Core;
using Volo.Abp;
using Volo.Abp.Application.Dtos;

namespace PHMEE.Admin
{
    public class CompanyAppService : PHMEEAdminAppService, ICompanyAppService
    {
        private readonly ICompanyManager companyManager;
        private readonly ICompanyRepository companyRepository;

        public CompanyAppService(ICompanyManager companyManager, ICompanyRepository companyRepository)
        {
            this.companyManager = companyManager;
            this.companyRepository = companyRepository;
        }

        [Authorize(PHMEEAdminPermissions.Companies.Create)]
        public async Task<Guid> CreateCompanyAsync(CompanyCreateDto input)
        {
            var company = await companyManager.CreateCompany(input.Name);

            company.Info = input.Info;

            company.UserIds = input.UserIds;

            await companyRepository.PhmeeCreate(company);

            return company.Id;
        }

        [Authorize(PHMEEAdminPermissions.Companies.Update)]
        public async Task UpdateCompanyAsync(CompanyUpdateDto input)
        {
            var query = await companyRepository.PhmeeGetQuery();

            if (query.Any(item => item.Name == input.Name && item.Id != input.Id))
            {
                throw new UserFriendlyException(L[PHMEEDomainErrorCodes.CompanyNameAlreadyExist], PHMEEDomainErrorCodes.CompanyNameAlreadyExist).WithData("Name", input.Name);
            }

            var company = await companyRepository.PhmeeGetById(input.Id);

            if (company == null)
            {
                throw new UserFriendlyException(L[PHMEEDomainErrorCodes.CompanyNotFound], PHMEEDomainErrorCodes.CompanyNotFound);
            }

            company.SetName(input.Name);

            company.Info = input.Info;

            company.UserIds = input.UserIds;

            await companyRepository.PhmeeUpdate(company);


        }

        [Authorize(PHMEEAdminPermissions.Companies.Delete)]
        public async Task DeleteCompanyAsync(Guid id)
        {
            await companyRepository.PhmeeDelete(id);
        }

        [Authorize(PHMEEAdminPermissions.Companies.Default)]
        public async Task<CompanyDto> GetCompanyByIdAsync(Guid id)
        {

            Company company = await companyRepository.PhmeeGetById(id);

            return ObjectMapper.Map<Company, CompanyDto>(company);

        }

        [Authorize(PHMEEAdminPermissions.Companies.Default)]
        public async Task<PagedResultDto<CompanyDto>> GetPagedCompaniesAsync(CompanyListDto input)
        {

            var query = await companyRepository.PhmeeGetQuery();

            query = query.WhereIf(!string.IsNullOrEmpty(input.Name), item => item.Name.Contains(input.Name)).OrderBy(input.Sorting ?? nameof(input.Name));

            var totalCount = query.Count();

            if (input.IsPaged)
            {
                query = query.PageBy(input.SkipCount, input.MaxResultCount);
            }

            var companies = await AsyncExecuter.ToListAsync(query);

            var items = ObjectMapper.Map<List<Company>, List<CompanyDto>>(companies);

            return new PagedResultDto<CompanyDto>(totalCount, items);

        }

    }
}
